package com.bkgy.controller.tbbxrecord.service.impl;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.bkgy.controller.acidefficiency.entity.*;
import com.bkgy.controller.acidefficiency.service.AcidEfficiencyService;
import com.bkgy.controller.acidefficiency.service.ITbTcm22280EffService;
import com.bkgy.controller.tbbxrecord.entity.ExcelSingleRoll;
import com.bkgy.controller.tbbxrecord.entity.TbBxFileSave;
import com.bkgy.controller.tbbxrecord.entity.TbBxSyncjob;
import com.bkgy.controller.tbbxrecord.service.ITbBxFileSaveService;
import com.bkgy.controller.tbbxrecord.service.ITbBxSyncService;
import com.bkgy.controller.tpdol3data.entity.TPdoDataL3Tcm2280;
import com.bkgy.controller.tpdol3data.service.ITPdoL3Tcm2280Service;
import com.bkgy.controller.tbbxrecord.dao.TbBxSyncJobDao;
import com.bkgy.sys.common.entity.ResultData;
import com.bkgy.util.DateUtil;
import com.bkgy.util.ExcelUtilsPOI;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

@Service
@RequiredArgsConstructor
public class TbBxSyncServiceImpl extends ServiceImpl<TbBxSyncJobDao, TbBxSyncjob> implements ITbBxSyncService {
    private final TbBxSyncJobDao mapper;
    private final ITbBxFileSaveService fileSaveService;
    private final ITPdoL3Tcm2280Service tcm2280Service;
    public final AcidEfficiencyService acidService;
    public final ITbTcm22280EffService tcm22280EffService;
    private final String lineStr = "TCM2280";

    @Override
    public ResultData<SingleRollListResp> selectPage(SingleRollListReq param) {
        Page<TbBxSyncjob> p = new Page<>(param.getPageIndex(), param.getPageSize());
        LambdaQueryWrapper<TbBxSyncjob> w1 = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(param.getEntid())) {
            w1.eq(TbBxSyncjob::getEntId, param.getEntid());
        }
        if (StringUtils.isNotEmpty(param.getStartDate())) {
            w1.ge(TbBxSyncjob::getProdEndTime, param.getStartDate());
        }
        if (StringUtils.isNotEmpty(param.getEndDate())) {
            w1.ge(TbBxSyncjob::getProdEndTime, param.getEndDate());
        }
        if (StringUtils.isNotEmpty(param.getSecReason())) {
            w1.like(TbBxSyncjob::getSecReason, param.getSecReason());
        }
        w1.isNotNull(TbBxSyncjob::getProdEndTime);
        w1.orderByDesc(TbBxSyncjob::getId);

        IPage<TbBxSyncjob> page = page(p, w1);
        List<SingleRollListResp> list = new ArrayList<>();
        for (TbBxSyncjob item : page.getRecords()) {
            SingleRollListResp obj = new SingleRollListResp();
            BeanUtils.copyProperties(item, obj);
            obj.setEntID(item.getEntId());
            obj.setExtID(item.getExtId());
            obj.setSteelGrade(item.getSteelgrade());
            if (item.getOutputSeActual() != null && item.getOutputSe() != null)
                obj.setDiff(item.getOutputSeActual() - item.getOutputSe());
            if (StringUtils.isNotEmpty(item.getProdEndTime())) {
                Date d = DateUtil.getStringToDate("yyyyMMddHHmmss", item.getProdEndTime());
                obj.setCreateTime(DateUtil.getDateToString(d, "yyyy-MM-dd HH:mm:ss"));
            }

            list.add(obj);
        }
        return ResultData.ResultDataSuccess(list, (int) page.getTotal());
    }

    @Override
    public ResultData<String> saveSingleRoll(SingleRollSaveReq req) {
        TbBxSyncjob syncjob = new TbBxSyncjob();
        syncjob.setSecReason(req.getSecReason());
        syncjob.setType(req.getType());

        LambdaUpdateWrapper<TbBxSyncjob> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(TbBxSyncjob::getExtId, req.getExtId());
        update(syncjob, queryWrapper);
        return ResultData.ResultDataSuccess("success");
    }

    @Override
    public void aosrpeExcel(SingleRollReq param, HttpServletResponse response) {
        LambdaQueryWrapper<TbBxSyncjob> w1 = new LambdaQueryWrapper<>();
        if (StringUtils.isNotEmpty(param.getEntid())) {
            w1.eq(TbBxSyncjob::getEntId, param.getEntid());
        }
        if (StringUtils.isNotEmpty(param.getStartDate())) {
            w1.ge(TbBxSyncjob::getProdEndTime, param.getStartDate());
        } else {
            //不设置开始时间导出一天的数据
            w1.ge(TbBxSyncjob::getProdEndTime, DateUtil.getDateToString(DateUtil.getBeforDate(), "yyyyMMddHHmmss"));
        }
        if (StringUtils.isNotEmpty(param.getEndDate())) {
            w1.ge(TbBxSyncjob::getProdEndTime, param.getEndDate());
        }
        if (StringUtils.isNotEmpty(param.getSecReason())) {
            w1.like(TbBxSyncjob::getSecReason, param.getSecReason());
        }
        w1.isNotNull(TbBxSyncjob::getProdEndTime);
        w1.orderByDesc(TbBxSyncjob::getId);
        List<TbBxSyncjob> dbList = list(w1);

        List<ExcelSingleRoll> list = new ArrayList<>();
        Map<String, String> map = new HashMap<String, String>();
        map.put("A", "甲");
        map.put("B", "乙");
        map.put("C", "丙");
        map.put("D", "丁");
        String[] typeArr = new String[]{"入口", "轧机", "圆盘剪", "焊接"};
        for (TbBxSyncjob obj : dbList) {
            ExcelSingleRoll excel = new ExcelSingleRoll();
            BeanUtils.copyProperties(obj, excel);

            if (StringUtils.isNotEmpty(obj.getProdEndTime())) {
                Date d = DateUtil.getStringToDate("yyyyMMddHHmmss", obj.getProdEndTime());
                excel.setCreateTime(DateUtil.getDateToString(d, "yyyy-MM-dd HH:mm:ss"));
            }
            excel.setShift(Integer.parseInt(obj.getShift()) == 1 ? "白" : "夜");
            excel.setCrew(map.get(obj.getCrew()));
            excel.setStopFlag(obj.getStopFlag() != null && obj.getStopFlag() == 1 ? "是" : "否");
            excel.setSlowFlag(obj.getSlowFlag() != null && obj.getSlowFlag() == 1 ? "是" : "否");
            if (obj.getType() != null)
                excel.setType(typeArr[obj.getType()]);
            if (excel.getOutputSeActual() != null && excel.getOutputSe() != null)
                excel.setDiff(excel.getOutputSeActual() - excel.getOutputSe());

            excel.setOutMatWidth(excel.getOutMatWidth().setScale(2, BigDecimal.ROUND_HALF_UP));
            excel.setOutMatThk(excel.getOutMatThk().setScale(3, BigDecimal.ROUND_HALF_UP));
            excel.setOutMatWt(excel.getOutMatWt().setScale(2, BigDecimal.ROUND_HALF_UP));

            BigDecimal rate = BigDecimal.valueOf(1000).multiply(BigDecimal.valueOf(1000));
            //入口理论小时产量[t/h]
            if (obj.getEnSpeedSet() != null) {
                BigDecimal c1 = obj.getEnSpeedSet().multiply(BigDecimal.valueOf(60));
                excel.setEnHourlyOutputSet(c1.multiply(obj.getOutMatThk().multiply(obj.getOutMatWidth()).multiply(BigDecimal.valueOf(7.8))).divide(rate).setScale(0, BigDecimal.ROUND_HALF_UP));
            }
            //入口实际小时产量[t/h]
            if (obj.getEnSpeedAvg() != null) {
                BigDecimal c2 = obj.getEnSpeedAvg().multiply(BigDecimal.valueOf(60));
                excel.setEnHourlyOutputReal(c2.multiply(obj.getOutMatThk().multiply(obj.getOutMatWidth()).multiply(BigDecimal.valueOf(7.8))).divide(rate).setScale(0, BigDecimal.ROUND_HALF_UP));
            }
            //酸洗理论小时产量[t/h]
            if (obj.getPlSpeedSet2() != null) {
                BigDecimal c3 = obj.getPlSpeedSet2().multiply(BigDecimal.valueOf(60));
                excel.setPickHourlyOutputSet(c3.multiply(obj.getOutMatThk().multiply(obj.getOutMatWidth()).multiply(BigDecimal.valueOf(7.8))).divide(rate).setScale(0, BigDecimal.ROUND_HALF_UP));
            }
            //酸洗实际小时产量[t/h]
            if (obj.getPickSpeed() != null) {
                BigDecimal c4 = obj.getPickSpeed().multiply(BigDecimal.valueOf(60));
                excel.setPickHourlyOutputReal(c4.multiply(obj.getOutMatThk().multiply(obj.getOutMatWidth()).multiply(BigDecimal.valueOf(7.8))).divide(rate).setScale(0, BigDecimal.ROUND_HALF_UP));
            }
            list.add(excel);
        }
        try {
            Map<String, Object> dataMap = new HashMap();
            dataMap.put("data", list);
            File file = ResourceUtils.getFile("classpath:exceltemplate\\酸轧单卷生产效率分析评价.xlsx");
            TemplateExportParams templ = new TemplateExportParams(file.getPath(), false);
            Workbook workbook = ExcelExportUtil.exportExcel(templ, dataMap);
            ExcelUtilsPOI.exportExcel("酸轧单卷生产效率分析评价", response, workbook);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public ResultData<Integer> getSingleRollSec(String entId) {
        int sec = 0;
        Integer s = mapper.getSingleRollSec(entId);
        if (s != null) {
            sec = s;
        }
        return ResultData.ResultDataSuccess(sec);
    }

    @Override
    public List<TbBxSyncjob> findBxData(String line, String coilId) {
        List<String> list = new ArrayList<>();
        list.add(coilId);
        return mapper.findBxData(line, list);
    }

    @Override
    public ResultData<String> buildBxSync(String id) {
        //获取同步记录
        LambdaQueryWrapper<TbBxFileSave> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TbBxFileSave::getIndocno, id);
        TbBxFileSave fileSave = fileSaveService.getOne(wrapper);
        if (fileSave != null) {
            String line = fileSave.getLine();
            String message = fileSave.getMessage();
            JSONObject json = JSONObject.parseObject(message);
            String entId = json.getString("entId");
            String extId = json.getString("extId");
            List<String> entIdList = new ArrayList<>();
            entIdList.add(entId);
            Set<String> extIdSet = new HashSet<>();
            extIdSet.add(extId);

            //加载秒用时记录
            Map<String, TbBxSyncjob> secMap = buildSec(lineStr, entIdList);
            //根据出口卷号查询产量
            Map<String, TPdoDataL3Tcm2280> tcmMap = buildTcmMap(extIdSet);
            //加载EnSpeedAvg,PickSpeed
            Map<String, TbTcm22280ProSpeed> speedMap = buildSpeedMap(extIdSet);
            //加载PorNo,EnSpeedSet,PlSpeedSet2
            Map<String, TbTcm22280Eff> effMap = buildEffMap(entIdList);

            TbBxSyncjob obj = new TbBxSyncjob();
            obj.setId(fileSave.getIndocno());
            obj.setLine(lineStr);
            obj.setEntId(entId);
            obj.setExtId(extId);
            TbBxSyncjob sec = secMap.get(entId);
            if (sec != null) {
                obj.setOutputSe(sec.getOutputSe());
                obj.setEndtime(sec.getEndtime());
                obj.setTctime(sec.getTctime());
                Date tcTime = sec.getTctime();
                Date endTime = sec.getEndtime();
                if (tcTime != null && endTime != null) {
                    long l = (endTime.getTime() - tcTime.getTime()) / 1000;
                    obj.setOutputSeActual((int) l);
                }

                TPdoDataL3Tcm2280 tcm = tcmMap.get(extId);
                if (tcm != null) {
                    obj.setSteelgrade(tcm.getSteelgrade());
                    obj.setProdEndTime(tcm.getProdEndTime());
                    obj.setOutMatThk(tcm.getOutMatThk());
                    obj.setOutMatWidth(tcm.getOutMatWidth());
                    obj.setOutMatWt(tcm.getOutMatWt());
                    obj.setShift(tcm.getShift());
                    obj.setCrew(tcm.getCrew());
                }

                TbTcm22280ProSpeed speed = speedMap.get(extId);
                if (speed != null) {
                    obj.setEnSpeedAvg(speed.getEnSpeedAvg());
                    obj.setPickSpeed(speed.getPickSpeed());
                }

                TbTcm22280Eff eff = effMap.get(entId);
                if (eff != null) {
                    obj.setPorNo(eff.getPorNo());
                    obj.setEnSpeedSet(eff.getEnSpeedSet());
                    obj.setPlSpeedSet2(eff.getPlSpeedSet2());
                }

                saveOrUpdate(obj);
            }
        }
        return ResultData.ResultDataSuccess("success");
    }

    @Override
    public ResultData<String> buildBxQujSync(String beginDate, String endDate) {
        List<TbBxSyncjob> saveList = new ArrayList<>();
        //查询区间记录
        LambdaQueryWrapper<TbBxFileSave> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TbBxFileSave::getLine, lineStr).ge(TbBxFileSave::getCreatetime, beginDate).le(TbBxFileSave::getCreatetime, endDate);
        List<TbBxFileSave> list = fileSaveService.list(wrapper);

        List<String> entIdList = new ArrayList<>();
        Map<String, TbBxSyncjob> extIdObjMap = new HashMap<>();
        for (TbBxFileSave fileSave : list) {
            String line = fileSave.getLine();
            String message = fileSave.getMessage();
            JSONObject json = JSONObject.parseObject(message);
            String entId = json.getString("entId");
            String extId = json.getString("extId");
            if (StringUtils.isEmpty(line) || StringUtils.isEmpty(entId)) {
                continue;
            }
            TbBxSyncjob obj = new TbBxSyncjob();
            obj.setId(fileSave.getIndocno());
            obj.setLine(line);
            obj.setEntId(entId);
            obj.setExtId(extId);

            entIdList.add(entId);
            extIdObjMap.put(extId, obj);
        }

        //加载秒用时记录
        Map<String, TbBxSyncjob> secMap = buildSec(lineStr, entIdList);
        //根据出口卷号查询产量
        Map<String, TPdoDataL3Tcm2280> tcmMap = buildTcmMap(extIdObjMap.keySet());
        //加载EnSpeedAvg,PickSpeed
        Map<String, TbTcm22280ProSpeed> speedMap = buildSpeedMap(extIdObjMap.keySet());
        //加载PorNo,EnSpeedSet,PlSpeedSet2
        Map<String, TbTcm22280Eff> effMap = buildEffMap(entIdList);

        //组合数据
        for (Map.Entry<String, TbBxSyncjob> entry : extIdObjMap.entrySet()) {
            String extId = entry.getKey();
            TbBxSyncjob obj = entry.getValue();
            String entId = obj.getEntId();

            TbBxSyncjob sec = secMap.get(entId);
            obj.setOutputSe(sec.getOutputSe());
            Date tcTime = sec.getTctime();
            Date endTime = sec.getEndtime();
            obj.setTctime(tcTime);
            obj.setEndtime(endTime);
            if (tcTime != null && endTime != null) {
                long l = (endTime.getTime() - tcTime.getTime()) / 1000;
                obj.setOutputSeActual((int) l);
            }

            TPdoDataL3Tcm2280 tcm = tcmMap.get(extId);
            if (tcm != null) {
                obj.setSteelgrade(tcm.getSteelgrade());
                obj.setShift(tcm.getShift());
                obj.setCrew(tcm.getCrew());
                obj.setOutMatWidth(tcm.getOutMatWidth());
                obj.setOutMatThk(tcm.getOutMatThk());
                obj.setOutMatWt(tcm.getOutMatWt());
                obj.setProdEndTime(tcm.getProdEndTime());
            }

            TbTcm22280ProSpeed speed = speedMap.get(extId);
            if (speed != null) {
                obj.setEnSpeedAvg(speed.getEnSpeedAvg());
                obj.setPickSpeed(speed.getPickSpeed());
            }

            TbTcm22280Eff eff = effMap.get(entId);
            if (eff != null) {
                obj.setPorNo(eff.getPorNo());
                obj.setEnSpeedSet(eff.getEnSpeedSet());
                obj.setPlSpeedSet2(eff.getPlSpeedSet2());
            }

            saveList.add(obj);
        }
        secMap.clear();
        tcmMap.clear();
        speedMap.clear();
        effMap.clear();

        saveBatch(saveList);

        return ResultData.ResultDataSuccess("success");
    }

    private Map<String, TbBxSyncjob> buildSec(String lineStr, List<String> entIdList) {
        List<TbBxSyncjob> bxData = mapper.findBxData(lineStr, entIdList);
        Map<String, TbBxSyncjob> secMap = new HashMap<>();
        for (TbBxSyncjob obj : bxData) {
            secMap.put(obj.getEntId(), obj);
        }
        return secMap;
    }

    private Map<String, TPdoDataL3Tcm2280> buildTcmMap(Set<String> extIdList) {
        LambdaQueryWrapper<TPdoDataL3Tcm2280> w1 = new LambdaQueryWrapper<>();
        w1.in(TPdoDataL3Tcm2280::getExtid, extIdList);
        Map<String, TPdoDataL3Tcm2280> tcmMap = new HashMap<>();
        List<TPdoDataL3Tcm2280> tcm2280List = tcm2280Service.list(w1);
        for (TPdoDataL3Tcm2280 tcm : tcm2280List) {
            tcmMap.put(tcm.getExtid(), tcm);
        }
        return tcmMap;
    }

    private Map<String, TbTcm22280ProSpeed> buildSpeedMap(Set<String> extIdList) {
        LambdaQueryWrapper<TbTcm22280ProSpeed> w2 = new LambdaQueryWrapper<>();
        w2.in(TbTcm22280ProSpeed::getExtid, extIdList);
        Map<String, TbTcm22280ProSpeed> speedMap = new HashMap<>();
        List<TbTcm22280ProSpeed> speedList = acidService.list(w2);
        for (TbTcm22280ProSpeed speed : speedList) {
            speedMap.put(speed.getExtid(), speed);
        }
        return speedMap;
    }

    private Map<String, TbTcm22280Eff> buildEffMap(List<String> entIdList) {
        LambdaQueryWrapper<TbTcm22280Eff> w3 = new LambdaQueryWrapper<>();
        w3.in(TbTcm22280Eff::getEntid, entIdList);
        List<TbTcm22280Eff> effList = tcm22280EffService.list(w3);
        Map<String, TbTcm22280Eff> effMap = new HashMap<>();
        for (TbTcm22280Eff eff : effList) {
            effMap.put(eff.getEntid(), eff);
        }
        return effMap;
    }
}
